﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace Tradex.Messages {

    /// <summary>
    /// Tradex applications are internally highly parallelized. As such, they deploy a message passing based achitecture.
    /// Subsystems call direct functions for administrative purposes on each other, but data flow (which is significant) is
    /// handled in the form of messages that are queued in many locations. As an example, a control contacts the MarketService
    /// via method call from it's intent to get market updates for an instrument. It gets back a subscription - for which the
    /// updates are available via an action callback. This callback powered by a separately threaded queue that the MarketService
    /// pushes the updates to - so that a slow control (or the slowness of the controls altogether) does not slow down the
    /// total system.
    /// 
    /// Messages are subclasses of this type (Messaage). Every subtype is responsible to implement one specific Code (that has to
    /// be unique), so that the receiver can use a simple switch statement to identify those messages he is interested in.
    /// 
    /// Messages must be serializable so that they can be exchanged bwtween process boundaries, to separate appdomains or external
    /// programs.
    /// 
    /// Messages generally fall into one of three categies:
    /// * Requests - asking the other party to deliver certain data or perform a certain operation.
    /// * Updates - which contain information to inform the other party of a certain activity or change in data.
    /// * Responses - which are sent in response to requests to inform the sender of the outcome of the request.
    /// </summary>
    [DataContract()]
    [KnownType ("MessageTypes")]
    public abstract class Message {

        /// <summary>
        /// Gets the numeric MessageCode which allows fast selection of the message type for handling routines.
        /// </summary>
        public abstract MessageCode Code { get; }

        /// <summary>
        /// Returns all used MessageTypes values.
        /// </summary>
        /// <returns></returns>
        static public IEnumerable<Type> MessageTypes() {
            return new Type[] {
                typeof(PingMessage),
                typeof(PongMessage),

                typeof(AccountsRequestMessage),
                typeof(AccountsUpdateMessage),
                typeof(AccountUpdateMessage),
                typeof(ConnectionUpdateMessage),
                typeof(InstrumentActivityRequest),
                typeof(InstrumentActivityUpdateMessage),
                typeof(InstrumentRequest),
                typeof(InstrumentUpdateMessage),
                typeof(LogEntryCreateMessage),
                typeof(OrderCreationRequestMessage),
                typeof(OrderModificationRequestMessage),
                typeof(OrderModificationResponseMessage),
                typeof(OrdersUpdateMessage),
                typeof(OrderUpdateMessage),
                typeof(PositionUpdateMessage),
                typeof(RequestResponseMessage)
            };
        }

    }
}
